<!DOCTYPE html>
<html lang="zh-CN,zh-TW,en,default">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.2.0">

<script data-ad-client="ca-pub-2746515851002080" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/font-awesome@4/css/font-awesome.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"lxxself.com","root":"/","scheme":"Muse","version":"7.7.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="近来项目中使用了https，然后发现对此不是十分了解，借此简单梳理一下。 https原理https简介HTTP 协议（HyperText Transfer Protocol，超文本传输协议）：是客户端浏览器或其他程序与Web服务器之间的应用层通信协议 。HTTPS 协议（HyperText Transfer Protocol over Secure Socket Layer）：可以理解为 HTTP">
<meta property="og:type" content="article">
<meta property="og:title" content="https原理和Android踩坑">
<meta property="og:url" content="http://lxxself.com/2018-04-02-%E6%8A%80%E6%9C%AF/2018-04-20/index.html">
<meta property="og:site_name" content="LXXSELF">
<meta property="og:description" content="近来项目中使用了https，然后发现对此不是十分了解，借此简单梳理一下。 https原理https简介HTTP 协议（HyperText Transfer Protocol，超文本传输协议）：是客户端浏览器或其他程序与Web服务器之间的应用层通信协议 。HTTPS 协议（HyperText Transfer Protocol over Secure Socket Layer）：可以理解为 HTTP">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://lxxself.qiniudn.com/15243198691328.jpg">
<meta property="article:published_time" content="2018-04-02T13:12:00.000Z">
<meta property="article:modified_time" content="2018-04-02T13:12:00.000Z">
<meta property="article:author" content="lxxself">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://lxxself.qiniudn.com/15243198691328.jpg">

<link rel="canonical" href="http://lxxself.com/2018-04-02-%E6%8A%80%E6%9C%AF/2018-04-20/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true
  };
</script>

  <title>https原理和Android踩坑 | LXXSELF</title>
  
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-101980994-1"></script>
    <script>
      if (CONFIG.hostname === location.hostname) {
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'UA-101980994-1');
      }
    </script>






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <div>
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">LXXSELF</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
        <p class="site-subtitle">Feel The World</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-fw fa-tags"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-fw fa-th"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档</a>

  </li>
        <li class="menu-item menu-item-file">

    <a href="http://dsm.lxx.im:9003/" rel="noopener" target="_blank"><i class="fa fa-fw fa-file"></i>文件</a>

  </li>
  </ul>

</nav>
</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content">
            

  <div class="posts-expand">
      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block " lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://lxxself.com/2018-04-02-%E6%8A%80%E6%9C%AF/2018-04-20/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Author">
      <meta itemprop="description" content="Feel The World">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="LXXSELF">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          https原理和Android踩坑
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2018-04-02 21:12:00" itemprop="dateCreated datePublished" datetime="2018-04-02T21:12:00+08:00">2018-04-02</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E6%8A%80%E6%9C%AF/" itemprop="url" rel="index"><span itemprop="name">技术</span></a>
                </span>
            </span>

          
  
  <span class="post-meta-item">
    
      <span class="post-meta-item-icon">
        <i class="fa fa-comment-o"></i>
      </span>
      <span class="post-meta-item-text">Disqus：</span>
    
    <a title="disqus" href="/2018-04-02-%E6%8A%80%E6%9C%AF/2018-04-20/#disqus_thread" itemprop="discussionUrl">
      <span class="post-comments-count disqus-comment-count" data-disqus-identifier="2018-04-02-技术/2018-04-20/" itemprop="commentCount"></span>
    </a>
  </span>
  
  

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <p>近来项目中使用了https，然后发现对此不是十分了解，借此简单梳理一下。</p>
<h1 id="https原理"><a href="#https原理" class="headerlink" title="https原理"></a>https原理</h1><h2 id="https简介"><a href="#https简介" class="headerlink" title="https简介"></a>https简介</h2><p>HTTP 协议（HyperText Transfer Protocol，超文本传输协议）：是客户端浏览器或其他程序与Web服务器之间的应用层通信协议 。<br>HTTPS 协议（HyperText Transfer Protocol over Secure Socket Layer）：可以理解为 HTTP+SSL/TLS， 即 HTTP 下加入 SSL 层，HTTPS 的安全基础是 SSL，因此加密的详细内容就需要 SSL，用于安全的 HTTP 数据传输。<br>原先的http协议使用的是明文传输，第三方可能会窃听、篡改、冒充。SSL/TLS协议就像是一道保护层，它的加入保证了：</p>
<ol>
<li>所有信息都是加密传播，第三方无法窃听。</li>
<li>具有校验机制，一旦被篡改，通信双方会立刻发现。</li>
<li>配备身份证书，防止身份被冒充。<h2 id="https原理-1"><a href="#https原理-1" class="headerlink" title="https原理"></a>https原理</h2><h3 id="1-客户端发出请求"><a href="#1-客户端发出请求" class="headerlink" title="1.客户端发出请求"></a>1.客户端发出请求</h3>客户端想服务器发起请求，发送：</li>
</ol>
<ul>
<li>协议版本号，比如TLS 1.0版</li>
<li>生成随机数C1</li>
<li>客户端支持的加密方式</li>
<li>支持的压缩方法<h3 id="2-服务器回应"><a href="#2-服务器回应" class="headerlink" title="2.服务器回应"></a>2.服务器回应</h3>服务器接收到请求，确认相关信息并作回应：</li>
<li>确认协议达成一致，否则关闭连接</li>
<li>生成随机数S1</li>
<li>选择一种加密方式，例如RSA公钥加密</li>
<li>服务器证书<h3 id="3-客户端验证"><a href="#3-客户端验证" class="headerlink" title="3.客户端验证"></a>3.客户端验证</h3>客户端收到回应后，对服务器证书进行认证：</li>
<li>是否是可信机构颁布</li>
<li>证书中的域名与实际域名不一致</li>
<li>证书有效期<br>验证通过后，取出证书中的公钥。<h3 id="4-客户端回应"><a href="#4-客户端回应" class="headerlink" title="4.客户端回应"></a>4.客户端回应</h3>生成随机数C2，并使用证书公钥非对称加密C2生成P，回应给服务器。客户端现在拥有随机数C1+C2+S1和约定的加密算法，生成”对话密钥”K。<h3 id="5-服务器回应"><a href="#5-服务器回应" class="headerlink" title="5.服务器回应"></a>5.服务器回应</h3>服务器接收到P，使用服务器证书私钥解密P得到随机数C2。服务器端也拥有了随机数C1+C2+S1和约定的加密算法，生成”对话密钥”K。然后之后客户端与服务器端的通信都使用K加密内容。<br><img src="http://lxxself.qiniudn.com/15243198691328.jpg"></li>
</ul>
<h1 id="Android踩坑"><a href="#Android踩坑" class="headerlink" title="Android踩坑"></a>Android踩坑</h1><p>在客户端交互的时候会涉及证书一说，一种是自己签发的证书，一种是第三方机构认证的证书。详细可查看<a target="_blank" rel="noopener" href="https://yq.aliyun.com/articles/109939">这个</a>。然而Android对此就会有以下两种情况。</p>
<h2 id="自签证书"><a href="#自签证书" class="headerlink" title="自签证书"></a>自签证书</h2><h3 id="信任所有证书"><a href="#信任所有证书" class="headerlink" title="信任所有证书"></a>信任所有证书</h3><p>对于任意的证书都可信任，简单，但有一定安全局限。<br>以OkHttp为例，所有重写方法不做任何的检验和校对。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> &#123;</span><br><span class="line"></span><br><span class="line">    internalHttpClientWithLongTimeout = <span class="keyword">new</span> OkHttpClient.Builder()</span><br><span class="line">            .connectTimeout(<span class="number">30</span>, TimeUnit.SECONDS)</span><br><span class="line">            .writeTimeout(<span class="number">30</span>, TimeUnit.SECONDS)</span><br><span class="line">            .readTimeout(<span class="number">30</span>, TimeUnit.SECONDS)</span><br><span class="line">            .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())</span><br><span class="line">            .hostnameVerifier(SSLSocketClient.getHostnameVerifier())</span><br><span class="line">            .proxy(Proxy.NO_PROXY)</span><br><span class="line">            .build();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SSLSocketClient</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//获取这个SSLSocketFactory</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> SSLSocketFactory <span class="title">getSSLSocketFactory</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            SSLContext sslContext = SSLContext.getInstance(<span class="string">&quot;SSL&quot;</span>);</span><br><span class="line">            sslContext.init(<span class="keyword">null</span>, getTrustManager(), <span class="keyword">new</span> SecureRandom());</span><br><span class="line">            <span class="keyword">return</span> sslContext.getSocketFactory();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(e);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//获取TrustManager</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> TrustManager[] getTrustManager() &#123;</span><br><span class="line">        TrustManager[] trustAllCerts = <span class="keyword">new</span> TrustManager[]&#123;</span><br><span class="line">                <span class="keyword">new</span> X509TrustManager() &#123;</span><br><span class="line">                    <span class="meta">@Override</span></span><br><span class="line">                    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">checkClientTrusted</span><span class="params">(X509Certificate[] chain, String authType)</span> </span>&#123;</span><br><span class="line">                    &#125;</span><br><span class="line"></span><br><span class="line">                    <span class="meta">@Override</span></span><br><span class="line">                    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">checkServerTrusted</span><span class="params">(X509Certificate[] chain, String authType)</span> </span>&#123;</span><br><span class="line">                    &#125;</span><br><span class="line"></span><br><span class="line">                    <span class="meta">@Override</span></span><br><span class="line">                    <span class="keyword">public</span> X509Certificate[] getAcceptedIssuers() &#123;</span><br><span class="line">                        <span class="keyword">return</span> <span class="keyword">new</span> X509Certificate[]&#123;&#125;;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="keyword">return</span> trustAllCerts;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//获取HostnameVerifier</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> HostnameVerifier <span class="title">getHostnameVerifier</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        HostnameVerifier hostnameVerifier = <span class="keyword">new</span> HostnameVerifier() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">verify</span><span class="params">(String s, SSLSession sslSession)</span> </span>&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;;</span><br><span class="line">        <span class="keyword">return</span> hostnameVerifier;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="只信任唯一证书"><a href="#只信任唯一证书" class="headerlink" title="只信任唯一证书"></a>只信任唯一证书</h3><p>将证书文件srca.cer 文件，复制到 Android 项目的 resource/raw/中。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">customTrust</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  X509TrustManager trustManager;</span><br><span class="line">  SSLSocketFactory sslSocketFactory;</span><br><span class="line">  <span class="comment">//读取自签名证书</span></span><br><span class="line">  InputStream cerIn = getResources().openRawResource(R.raw.srca);</span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="comment">//通过trustManagerForCertificates方法为证书生成 TrustManager</span></span><br><span class="line">      trustManager = trustManagerForCertificates(cerIn);</span><br><span class="line">      SSLContext sslContext = SSLContext.getInstance(<span class="string">&quot;TLS&quot;</span>);</span><br><span class="line">      sslContext.init(<span class="keyword">null</span>, <span class="keyword">new</span> TrustManager[]&#123;trustManager&#125;, <span class="keyword">null</span>);</span><br><span class="line">      sslSocketFactory = sslContext.getSocketFactory();</span><br><span class="line">  &#125; <span class="keyword">catch</span> (GeneralSecurityException e) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(e);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//设置 OkHttpClient</span></span><br><span class="line">  mOkHttpClient = <span class="keyword">new</span> OkHttpClient.Builder()</span><br><span class="line">                  .sslSocketFactory(sslSocketFactory, trustManager)</span><br><span class="line">                  .build();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> X509TrustManager <span class="title">trustManagerForCertificates</span><span class="params">(InputStream in)</span> </span></span><br><span class="line"><span class="function">  <span class="keyword">throws</span> GeneralSecurityException </span>&#123;</span><br><span class="line">  <span class="comment">//InputStream 可以包含多个证书</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">//CertificateFactory 用于生成 Certificate，也就是数字证书</span></span><br><span class="line">  CertificateFactory certificateFactory = CertificateFactory.getInstance(<span class="string">&quot;X.509&quot;</span>);</span><br><span class="line">  <span class="comment">//由输入流生成证书</span></span><br><span class="line">  Collection&lt;? extends Certificate&gt; certificates = certificateFactory.generateCertificates(in);</span><br><span class="line">  <span class="keyword">if</span> (certificates.isEmpty()) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">&quot;expected non-empty set of trusted certificates&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 将证书放入 keyStore</span></span><br><span class="line">  <span class="keyword">char</span>[] password = <span class="string">&quot;password&quot;</span>.toCharArray(); <span class="comment">// &quot;password&quot;可以任意设置</span></span><br><span class="line">  KeyStore keyStore = newEmptyKeyStore(password);</span><br><span class="line">  <span class="keyword">int</span> index = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">for</span> (Certificate certificate : certificates) &#123;</span><br><span class="line">      String certificateAlias = Integer.toString(index++);</span><br><span class="line">      keyStore.setCertificateEntry(certificateAlias, certificate);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 用　KeyStore 生成 X509 trust manager.</span></span><br><span class="line">   KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(</span><br><span class="line">              KeyManagerFactory.getDefaultAlgorithm());</span><br><span class="line">  keyManagerFactory.init(keyStore, password);</span><br><span class="line">  TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(</span><br><span class="line">              TrustManagerFactory.getDefaultAlgorithm());</span><br><span class="line">      trustManagerFactory.init(keyStore);</span><br><span class="line">  TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();</span><br><span class="line">  <span class="keyword">if</span> (trustManagers.length != <span class="number">1</span> || !(trustManagers[<span class="number">0</span>] <span class="keyword">instanceof</span> X509TrustManager)) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">&quot;Unexpected default trust managers:&quot;</span> + Arrays.toString(trustManagers));</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> (X509TrustManager) trustManagers[<span class="number">0</span>];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">static</span> KeyStore <span class="title">newEmptyKeyStore</span><span class="params">(<span class="keyword">char</span>[] password)</span> <span class="keyword">throws</span> GeneralSecurityException </span>&#123;</span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">      KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());</span><br><span class="line">      InputStream in = <span class="keyword">null</span>;</span><br><span class="line">      <span class="comment">// 传入 &#x27;null&#x27; 会生成一个空的 Keytore</span></span><br><span class="line">      <span class="comment">//password 用于检查 KeyStore 完整性和 KeyStore 解锁</span></span><br><span class="line">      keyStore.load(in, password);</span><br><span class="line">      <span class="keyword">return</span> keyStore;</span><br><span class="line">  &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> AssertionError(e);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="数字证书签发机构（CA）颁发的证书"><a href="#数字证书签发机构（CA）颁发的证书" class="headerlink" title="数字证书签发机构（CA）颁发的证书"></a>数字证书签发机构（CA）颁发的证书</h2><p>如果是这种情况，且该权威CA内置于系统内部，那么代码无需做任何处理。</p>
<h1 id="参考引用"><a href="#参考引用" class="headerlink" title="参考引用"></a>参考引用</h1><blockquote>
<p><a target="_blank" rel="noopener" href="https://www.zhihu.com/question/33645891">https://www.zhihu.com/question/33645891</a><br><a target="_blank" rel="noopener" href="http://pingguohe.net/2016/02/26/Android-App-secure-ssl.html">http://pingguohe.net/2016/02/26/Android-App-secure-ssl.html</a><br><a target="_blank" rel="noopener" href="https://jaq.alibaba.com/community/art/show?articleid=545">https://jaq.alibaba.com/community/art/show?articleid=545</a><br><a target="_blank" rel="noopener" href="https://yq.aliyun.com/articles/109939">https://yq.aliyun.com/articles/109939</a></p>
</blockquote>

    </div>

    
    
    

      <footer class="post-footer">

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2017-05-15-%E9%81%87%E8%A7%81/V2Ray%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%E5%92%8C%E9%85%8D%E7%BD%AE%E8%AE%B0%E5%BD%95/" rel="prev" title="V2Ray环境搭建和配置记录">
      <i class="fa fa-chevron-left"></i> V2Ray环境搭建和配置记录
    </a></div>
      <div class="post-nav-item">
    <a href="/2020-03-17-%E8%AE%B0%E5%BD%95/%E4%BF%AE%E6%94%B9Next%E4%B8%BB%E9%A2%98%E9%A6%96%E9%A1%B5%E6%91%98%E8%A6%81%E6%98%BE%E7%A4%BA/" rel="next" title="修改Next主题首页摘要显示">
      修改Next主题首页摘要显示 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  

  </div>


          </div>
          
    
  <div class="comments">
    <div id="disqus_thread">
      <noscript>Please enable JavaScript to view the comments powered by Disqus.</noscript>
    </div>
  </div>
  

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#https%E5%8E%9F%E7%90%86"><span class="nav-number">1.</span> <span class="nav-text">https原理</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#https%E7%AE%80%E4%BB%8B"><span class="nav-number">1.1.</span> <span class="nav-text">https简介</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#https%E5%8E%9F%E7%90%86-1"><span class="nav-number">1.2.</span> <span class="nav-text">https原理</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%8F%91%E5%87%BA%E8%AF%B7%E6%B1%82"><span class="nav-number">1.2.1.</span> <span class="nav-text">1.客户端发出请求</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%9B%9E%E5%BA%94"><span class="nav-number">1.2.2.</span> <span class="nav-text">2.服务器回应</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%AA%8C%E8%AF%81"><span class="nav-number">1.2.3.</span> <span class="nav-text">3.客户端验证</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%9B%9E%E5%BA%94"><span class="nav-number">1.2.4.</span> <span class="nav-text">4.客户端回应</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%9B%9E%E5%BA%94"><span class="nav-number">1.2.5.</span> <span class="nav-text">5.服务器回应</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#Android%E8%B8%A9%E5%9D%91"><span class="nav-number">2.</span> <span class="nav-text">Android踩坑</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%87%AA%E7%AD%BE%E8%AF%81%E4%B9%A6"><span class="nav-number">2.1.</span> <span class="nav-text">自签证书</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BF%A1%E4%BB%BB%E6%89%80%E6%9C%89%E8%AF%81%E4%B9%A6"><span class="nav-number">2.1.1.</span> <span class="nav-text">信任所有证书</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8F%AA%E4%BF%A1%E4%BB%BB%E5%94%AF%E4%B8%80%E8%AF%81%E4%B9%A6"><span class="nav-number">2.1.2.</span> <span class="nav-text">只信任唯一证书</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%95%B0%E5%AD%97%E8%AF%81%E4%B9%A6%E7%AD%BE%E5%8F%91%E6%9C%BA%E6%9E%84%EF%BC%88CA%EF%BC%89%E9%A2%81%E5%8F%91%E7%9A%84%E8%AF%81%E4%B9%A6"><span class="nav-number">2.2.</span> <span class="nav-text">数字证书签发机构（CA）颁发的证书</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%8F%82%E8%80%83%E5%BC%95%E7%94%A8"><span class="nav-number">3.</span> <span class="nav-text">参考引用</span></a></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">Author</p>
  <div class="site-description" itemprop="description">Feel The World</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">56</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">6</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">3</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Author</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> 强力驱动 v5.2.0
  </div>
  <span class="post-meta-divider">|</span>
  <div class="theme-info">主题 – <a href="https://muse.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Muse</a> v7.7.2
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="//cdn.jsdelivr.net/npm/animejs@3.1.0/lib/anime.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/velocity-animate@1/velocity.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/velocity-animate@1/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/muse.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

<script>
  function loadCount() {
    var d = document, s = d.createElement('script');
    s.src = 'https://lxxself.disqus.com/count.js';
    s.id = 'dsq-count-scr';
    (d.head || d.body).appendChild(s);
  }
  // defer loading until the whole page loading is completed
  window.addEventListener('load', loadCount, false);
</script>
<script>
  var disqus_config = function() {
    this.page.url = "http://lxxself.com/2018-04-02-%E6%8A%80%E6%9C%AF/2018-04-20/";
    this.page.identifier = "2018-04-02-技术/2018-04-20/";
    this.page.title = "https原理和Android踩坑";
    };
  NexT.utils.loadComments(document.querySelector('#disqus_thread'), () => {
    if (window.DISQUS) {
      DISQUS.reset({
        reload: true,
        config: disqus_config
      });
    } else {
      var d = document, s = d.createElement('script');
      s.src = 'https://lxxself.disqus.com/embed.js';
      s.setAttribute('data-timestamp', '' + +new Date());
      (d.head || d.body).appendChild(s);
    }
  });
</script>

</body>
</html>
